package com.syn.vr.cic;

import android.app.ActivityManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;

import com.gaoyi.basemodule.baseUtil.ToastUtil;

import java.io.File;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.List;

import com.moniuliuma.android.mupl.dt;
import com.syn.vr.activity.JumpActivity;
import com.syn.vr.constant.BundleKeyName;

import java.util.Locale;

/**
 * Created by raymondsung on 7/7/2015.
 */
public class BiometricDeviceService extends Service {
    private static boolean bCICDevice = false;

    private long lastTime;

    static {
        try {
            File libFile = new File("/system/lib/iinterface.so");
            if (libFile.exists()) {
                System.loadLibrary("/system/lib/iinterface.so");
//                System.load("/system/lib/iinterface.so");
                Log.d("BiometricDeviceService", "System.load");
                bCICDevice = true;
            } else
                Log.d("BiometricDeviceService", "no loadLibrary");
        } catch (Exception e) {
            Log.d("BiometricDeviceService", "Cannot Load iinterface.so - Probably non-CIC Device");
        }

    }


    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        Log.d("BiometricDeviceService", "onBind");
        Log.d("BiometricDeviceService", mBinder.toString());
        return mBinder;
    }

    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        try {
            for (int i = 0; i < len; i += 2) {
                data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                        + Character.digit(s.charAt(i + 1), 16));
            }
        } catch (Exception e) {
            Log.d("BiometricDeviceService", "Argument(s) for hexStringToByteArray(String s)"
                    + "was not a hex string");
        }
        return data;
    }

    private void send_wiegand(String CWRNo, String serialNo, boolean isWg34) {
        String mMachineidReverse = "";
        byte[] wgData34 = new byte[4];
        byte[] wgData26 = new byte[3];

        //SerialNo:518BB900
        //EverApex: b9 8b 51

        if (CWRNo.startsWith("CWR")) {
            int id = Integer.parseInt(CWRNo.substring(3));
            if (isWg34) {
                wgData34[0] = (byte) ((id >> 24) & 0xff);
                wgData34[1] = (byte) ((id >> 16) & 0xff);
                wgData34[2] = (byte) ((id >> 8) & 0xff);
                wgData34[3] = (byte) (id & 0xff);
            } else {
                wgData26[0] = (byte) ((id >> 16) & 0xff);
                wgData26[1] = (byte) ((id >> 8) & 0xff);
                wgData26[2] = (byte) (id & 0xff);
            }
        } else {
            if (isWg34) {
                mMachineidReverse = serialNo.substring(6, 8) + serialNo.substring(4, 6) + serialNo.substring(2, 4) + serialNo.substring(0, 2);
                wgData34 = hexStringToByteArray(mMachineidReverse);
            } else {
                mMachineidReverse = serialNo.substring(4, 6) + serialNo.substring(2, 4) + serialNo.substring(0, 2);
                wgData26 = hexStringToByteArray(mMachineidReverse);
            }
        }

        dt dt = new dt();
        dt.uart_debug(true);

        dt.uart_power(1, com.moniuliuma.android.mupl.dt.UART_DEVICE_WIEGAND);
        dt.uart_open(dt.UART_ID_1, 9600, 8, 1, 'N');

        if (isWg34) {
            dt.uart_write(wgData34);
        } else {
            dt.uart_write(wgData26);
        }

        dt.uart_close();
        dt.uart_power(0, com.moniuliuma.android.mupl.dt.UART_DEVICE_WIEGAND);
    }

    private String getCardNo(String serialNo, String cwrNo) {
        serialNo = serialNo.toLowerCase();
        if (cwrNo != null && cwrNo.startsWith("CWR")) {
            return cwrNo.replace("CWR", "");
        } else {
            if (serialNo.length() != 8) {
                ToastUtil.showToast("invalid cardNo");
                return null;
            }
            String mMachineidReverse = serialNo.substring(6, 8) + serialNo.substring(4, 6) + serialNo.substring(2, 4) + serialNo.substring(0, 2);
            return new BigInteger(mMachineidReverse, 16).toString(10);
        }
    }


    private final IBioTemplateService.Stub mBinder = new IBioTemplateService.Stub() {
        @Override
        public String RequestTemplate(String sessionId) throws RemoteException {
            Log.d("BiometricDeviceService", "RequestTemplate() sessionId:" + sessionId);
            return "";
        }

        @Override
        public int SetTemplateMode(int templateMode) throws RemoteException {
            Log.d("BiometricDeviceService", "SetTemplateMode()  templateMode:" + templateMode);
            return 1;
        }


        @Override
        public String VerifyTemplate(String sessionId, String CWRNo, String template, String writeDate, String writerId, String serialNo, String greenCardExpire) throws RemoteException {
            Log.d("BiometricDeviceService", "Enter VerifyTemplate");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ENGLISH);
            String logmsg = sdf2.format(new java.util.Date()) + " sessionId:" + sessionId + ", CWRNo:" + CWRNo + ", template:" + template + ", writeDate:" + writeDate + ", writeId:" + writerId + ", SerialNo:" + serialNo + ", greenCardExpire: " + greenCardExpire;


            Log.d("BiometricDeviceService", "VerifyTemplate() Before Send Wiegand");
            send_wiegand(CWRNo, serialNo, true);
            serialNo = getCardNo(serialNo, CWRNo);
            Log.d("BiometricDeviceService", "VerifyTemplate() params:" + logmsg);
            String strReturn = "{\"SessionId\":\"" + sessionId + "\", \"CWRNo\": \"" + CWRNo + "\", \"Result\":\"1\", \"Datetime\": \"" + sdf.format(new java.util.Date()) + "\"}";
            Log.d("BiometricDeviceService", "VerifyTemplate() return:" + strReturn);
            String finalSerialNo = serialNo;

            if (System.currentTimeMillis() - lastTime > 2000) {
                if (isAppAlive(getApplicationContext(), "com.syn.vr")) {
                    finalSerialNo = finalSerialNo.replaceAll("^0*", "");
                    Log.i("TAG", "VerifyTemplate: " + finalSerialNo);
                    jumpWithNo(finalSerialNo);
                    Log.d("zkzk", "已啟動");
                } else {
                    Log.d("zkzk", "未啟動");
                    Intent intent = getPackageManager().getLaunchIntentForPackage("com.syn.vr");
                    if (intent != null) {
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        intent.putExtra("isFinish", true);
                        startActivity(intent);
                    }
                }

                Log.d("zkzk", "starg===");
            }


            Log.d("zkzk", "msg==============" + lastTime);
            lastTime = System.currentTimeMillis();

            return strReturn;
        }
    };

    private void jumpWithNo(String finalSerialNo) {
        if (TextUtils.isEmpty(finalSerialNo)) {
            return;
        }
        Log.i("TAG", "jumpWithNo: "+finalSerialNo);
        Intent intent = new Intent(getApplicationContext(), JumpActivity.class);
        intent.putExtra(BundleKeyName.CARD_NO, finalSerialNo);
        startActivity(intent);
    }

    public static boolean isAppAlive(Context context, String packageName) {
        ActivityManager activityManager =
                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> processInfos
                = activityManager.getRunningAppProcesses();
        for (int i = 0; i < processInfos.size(); i++) {
            if (processInfos.get(i).processName.equals(packageName)) {
                Log.i("NotificationLaunch",
                        String.format("the %s is running, isAppAlive return true", packageName));
                return true;
            }
        }
        Log.i("NotificationLaunch",
                String.format("the %s is not running, isAppAlive return false", packageName));
        return false;
    }
}